package com.hex.ds.hdrs.app.service.impl;


import cn.hutool.core.collection.CollectionUtil;
import com.hex.bigdata.hbda.service.UserService;
import com.hex.bigdata.hbda.service.dto.RoleSmallDto;
import com.hex.bigdata.hbda.service.dto.UserDto;
import com.hex.bigdata.hbda.utils.StringUtils;
import com.hex.ds.hdrs.app.converter.IAppAdminRelationConverter;
import com.hex.ds.hdrs.app.dao.AppAdminRelationDao;
import com.hex.ds.hdrs.app.dto.AppAdminRelationDto;
import com.hex.ds.hdrs.app.po.AppAdminRelationPo;
import com.hex.ds.hdrs.app.po.MenuPo;
import com.hex.ds.hdrs.app.service.IAppAdminRelationService;
import com.hex.ds.hdrs.common.constant.Const;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;


/**
 * @Package com.hex.ds.hdrs.app.service.impl
 * @ClassName AppAdminRelationServiceImpl
 * @Description 应用与管理员用户关联表业务实现
 * @Author yu liuyang
 * @Date 2023/4/16 10:24
 * @Version v1.0
 **/
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class AppAdminRelationServiceImpl implements IAppAdminRelationService {

    private final AppAdminRelationDao appAdminRelationDao;

    private final UserService userService;

    private final IAppAdminRelationConverter appAdminRelationConverter;

    /**
     * @Method queryList <br>
     * @Param [appAdminRelationDto] <br>
     * @Return java.util.List<com.hex.ds.hdrs.app.po.AppAdminRelation> <br>
     * @Description 查询应用与管理员关联列表 <br>
     * @Author yu liuyang <br>
     * @Date 2023/4/17 15:48 <br>
     * @Version V1.0 <br>
     */
    public List<AppAdminRelationPo> queryList(AppAdminRelationDto appAdminRelationDto) {
        return appAdminRelationDao.queryList(appAdminRelationConverter.toAppAdminRelation(appAdminRelationDto));
    }

    /*
     * @Method: queryList <br>
     * @Param: [userName, appCode] <br>
     * @Return: java.util.List<com.hex.ds.hdrs.app.po.AppAdminRelationPo> <br>
     * @Description：根据用户名和应用编码查询两者直接的关系<br>
     * @Author： wz.li<br>
     * @Date： 2023/6/1 11:52 <br>
     * @Version： V2.0.2<br>
     */
    @Override
    public List<AppAdminRelationPo> queryList(String userName, String appCode) {
        AppAdminRelationPo appAdminRelation = new AppAdminRelationPo(appCode, userName);
        return appAdminRelationDao.queryList(appAdminRelation);
    }


    /**
     * @Method add <br>
     * @Param [appAdminRelationDto] <br>
     * @Return void <br>
     * @Description 添加应用与管理员关联 <br>
     * @Author yu liuyang <br>
     * @Date 2023/4/17 15:46 <br>
     * @Version V1.0 <br>
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void add(AppAdminRelationDto appAdminRelationDto, List<String> adminList) {
        if (CollectionUtil.isNotEmpty(adminList) && StringUtils.isNotBlank(appAdminRelationDto.getAppCode())) {
            adminList.stream().forEach((adminUser) -> {
                addAppAdminRelation(appAdminRelationDto, adminUser);
            });
        }
    }

    /**
     * @Method addAppAdminRelation <br>
     * @Param [appAdminRelationDto, adminUser] <br>
     * @Return void <br>
     * @Description  <br>
     * @Author yu liuyang <br>
     * @Date 2023/4/18 16:02 <br>
     * @Version V1.0 <br>
     */
    private void addAppAdminRelation(AppAdminRelationDto appAdminRelationDto, String adminUser) {
        AppAdminRelationPo appAdminRelationPo = appAdminRelationConverter.toAppAdminRelation(appAdminRelationDto).setAdminUserCode(adminUser);
        appAdminRelationPo.setAdminUserCode(userService.findByName(appAdminRelationPo.getAdminUserCode()).getUsername());
        int count = appAdminRelationDao.insert(appAdminRelationPo);
        if (count != 1) {
            throw new RuntimeException("添加应用与管理员关联失败！");
        }
    }

    /**
     * @Method addAdmin <br>
     * @Param  [appAdminRelationDto]<br>
     * @Return  void<br>
     * @Description 添加管理员<br>
     * @Author yu liuyang <br>
     * @Date 2023/4/16 10:19 <br>
     * @Version V1.0 <br>
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void addAdmin(AppAdminRelationDto appAdminRelationDto) {
        //添加运维管理员
        appAdminRelationDto.setAdminType("1");
        add(appAdminRelationDto, appAdminRelationDto.getDevAdmins());
        //添加监控管理员
        appAdminRelationDto.setAdminType("2");
        add(appAdminRelationDto, appAdminRelationDto.getMonitorAdmins());
        //添加发布管理员
        appAdminRelationDto.setAdminType("3");
        add(appAdminRelationDto, appAdminRelationDto.getReleaseAdmins());
    }


    /**
     * @Method addAppUser <br>
     * @Param [userDto, appCode] <br>
     * @Return void <br>
     * @Description 添加应用管理用户<br>
     * @Author yu liuyang <br>
     * @Date 2023/4/16 10:19 <br>
     * @Version V1.0 <br>
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void addAppUser(UserDto userDto, String appCode) {
        if (userDto != null && StringUtils.isNotBlank(appCode)) {
            remove(appCode, userDto.getUsername());
            AppAdminRelationPo appAdminRelationPo = appAdminRelationConverter.userDtoToAppAdminRelation(userDto).setAppCode(appCode);
            Set<RoleSmallDto> roles = userDto.getRoles();
            roles.stream().filter((role) -> role != null && role.getId() != null).forEach((role) -> {
                setAdminTypeAndInsert(appAdminRelationPo, role);
            });
        }
    }

    /**
     * @Method setAdminTypeAndInsert <br>
     * @Param [appAdminRelation, role] <br>
     * @Return void <br>
     * @Description 插入应用与管理员关联 <br>
     * @Author yu liuyang <br>
     * @Date 2023/4/16 10:20 <br>
     * @Version V1.0 <br>
     */
    private void setAdminTypeAndInsert(AppAdminRelationPo appAdminRelationPo, RoleSmallDto role) {
        if ("109".equals(Long.toString(role.getId()))) {
            appAdminRelationPo.setAdminType(Const.DEV_ADMINS_TYPE);
        }
        if ("110".equals(Long.toString(role.getId()))) {
            appAdminRelationPo.setAdminType(Const.MONITOR_ADMINS_TYPE);
        }
        if ("111".equals(Long.toString(role.getId()))) {
            appAdminRelationPo.setAdminType(Const.RELEASE_ADMINS_TYPE);
        }
        int count = appAdminRelationDao.insert(appAdminRelationPo);
        if (count != 1) {
            throw new RuntimeException("添加失败！");
        }
    }

    /**
     * @Method modifyByAppCode <br>
     * @Param [appAdminRelationDto] <br>
     * @Return void <br>
     * @Description 根据AppCode修改引用管理员关联 <br>
     * @Author yu liuyang <br>
     * @Date 2023/4/16 10:21 <br>
     * @Version V1.0 <br>
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void modifyByAppCode(AppAdminRelationDto appAdminRelationDto) {
        removeByAppCode(appAdminRelationDto.getAppCode());
        addAdmin(appAdminRelationDto);
    }

    /**
     * @Method remove <br>
     * @Param [appCode, adminUserCode] <br>
     * @Return void <br>
     * @Description 根据应用编码或管理员用户编码 <br>
     * @Author yu liuyang <br>
     * @Date 2023/4/18 15:14 <br>
     * @Version V1.0 <br>
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void remove(String appCode, String adminUserCode) {
        appAdminRelationDao.delete(new AppAdminRelationPo(appCode, adminUserCode));
    }

    /*
     * @Method: removeByAppCode <br>
     * @Param: [appCode] <br>
     * @Return: void <br>
     * @Description：根据应用编码删除<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/23 17:10 <br>
     * @Version： V2.0.2<br>
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void removeByAppCode(String appCode) {
        remove(appCode, null);
    }

    @Override
    public List<MenuPo> queryPermissionByRoleId(String roleId) {
        return appAdminRelationDao.queryPermissionByRoleId(roleId);
    }

}
